<?php

namespace App\HttpController;


use App\Common\Log;
use App\Common\OA\OAUser;
use App\ModelBase\AppModel;
use XWX\Common\H;
use XWX\Common\XReturn;

class ControllerAdmin extends ControllerBase
{
    public $pub_token_key = 'token';


    /**
     * 获取token
     *
     * @return string
     */
    private function token()
    {
        $token_enc = $this->reqParam($this->pub_token_key);
        $token = base64_decode($token_enc);
        if ($token == false)
        {
            $token = '';
        }

        return $token;
    }

    /**
     * 登陆管理员对象
     * @return OAUser
     * @throws \Exception
     */
    function funcGetOAUser()
    {
        $app_user = $this->context()->get('app_user');
        if ($app_user == null)
        {
            $app_user = new OAUser($this->token());
        }

        return $app_user;
    }

    function funcGetX()
    {
        return $this->funcGetOAUser()->x;
    }


    function getID()
    {
        return $this->reqParam('id');
    }

    function getPID()
    {
        return $this->reqParam('pid');
    }

    function getAppID()
    {
        return $this->reqParam('app_id');
    }


    /**
     * 添加操作
     * @return bool
     */
    function funcIsAdminAdd()
    {
        return H::funcStrIsNullOrEmpty($this->getID());
    }

    /**
     * 编辑操作
     * @return bool
     */
    function funcIsAdminEdit()
    {
        return !$this->funcIsAdminAdd();
    }


    /**
     * 导出操作
     * @return bool
     */
    function funcIsAdminExport()
    {
        return H::funcStrHasAnyText($this->reqParam('__export__'));
    }


    public function funcExport($data_query, $table_name, $table_head, callable $handle_data_func = null)
    {
        if (!method_exists($this, 'ExportCsvHead'))
        {
            throw new \Exception('请引用TraitExcel导出插件');
        }


        $this->ExportCsvHead();

        $export_page_index = 1;
        $export_page_size = 5000;
        $exclude_head = false;
        for ($i = 1; $i <= 20; $i++) //最多导10万
        {
            $page_index = ($export_page_index - 1) * $export_page_size;

            $export_query = clone($data_query);
            $list = $export_query->get($table_name, [$page_index, $export_page_size]);
            if (count($list) <= 0)
            {
                //查询数据返回空，跳出
                break;
            }


            $table_data = [];
            if ($handle_data_func !== null)
            {
                //特殊处理导出数据
                foreach ($list as $row)
                {
                    $data = $handle_data_func($row);

                    $table_data[] = $data;
                }
            }
            else
            {
                $table_data = $list;
            }

            $ex_data = $this->ExportSetData($table_head, $table_data, $exclude_head);
            $this->ExportCsvAddData($ex_data);

            $exclude_head = true;
            $export_page_index++;
        }
    }


    /**
     * 保存
     *
     * @param $class_name
     * @param null $ignore_field 排除字段
     * @param bool $auto_set_id true:自动设置ID;false:手动设置ID
     * @throws \EasySwoole\Mysqli\Exceptions\ConnectFail
     * @throws \Throwable
     */
    final public function funcSave($class_name, $ignore_field = null, $auto_set_id = true)
    {
        Log::funcLog(__METHOD__);

        $this->db()->startTransaction();
        try
        {
            //排除不更新字段
            $data = $this->request()->getRequestParam();
            $data = array_filter($data, function ($v, $k) use ($ignore_field)
            {
                return !in_array($k, $ignore_field);
            }, ARRAY_FILTER_USE_BOTH);


            /** @var AppModel $entity */
            $entity = new $class_name();
            $entity->fill($data, true);
            Log::funcLog(__METHOD__, 'funcSaveBefore');
            $this->funcSaveBefore($entity);

            $res = false;
            if ($this->funcIsAdminAdd())
            {
                $entity->funcSetX($this->funcGetX());
                if ($auto_set_id)
                {
                    $entity->funcSetAutoID();
                }
                $res = $entity->funcInsert();
            }
            else
            {
                $res = $entity->funcUpdate();
            }

            if ($res == false)
            {
                $errmsg = $this->db()->getLastError();
                $this->commonR()->errcode = -123456;
                $this->commonR()->errmsg = '保存失败,' . $errmsg;
            }

            Log::funcLog(__METHOD__, 'funcSaveAfter');
            $this->funcSaveAfter($entity);
        }
        catch (\Exception $ex)
        {
            throw $ex;
        }
        finally
        {
            $this->db()->commit();
        }


        $this->commonR()->setData('is_admin_add', $this->funcIsAdminAdd());
    }

    /**
     * 保存之前
     *
     * @param AppModel $entity
     */
    public function funcSaveBefore($entity)
    {

    }

    /**
     * 保存之后
     *
     * @param AppModel $entity
     */
    public function funcSaveAfter($entity)
    {
    }


    /**
     * 删除
     *
     * @param $class_name
     * @param $ids
     * @return XReturn
     * @throws \EasySwoole\Mysqli\Exceptions\ConnectFail
     * @throws \EasySwoole\Mysqli\Exceptions\PrepareQueryFail
     * @throws \Throwable
     */
    public function funcDel($class_name, $ids)
    {
        if (is_string($ids))
        {
            if (H::funcStrIsNullOrEmpty($ids))
            {
                return $this->funcGetR(-1180, '缺少重要参数');
            }

            $ids = explode(',', $ids);
        }

        if (count($ids) <= 0)
        {
            return $this->funcGetR(-1190, '至少选择一项');
        }


        /** @var AppModel $entity */
        $entity = new $class_name();
        $res = $this->db()->whereIn($entity->funcIdKey(), $ids)
            ->delete($entity::table());
        if ($res == false)
        {
            $errmsg = '删除失败,' . $this->db()->getLastError();

            return $this->funcGetR(-123456, $errmsg);
        }

        $r = $this->funcGetR(0, '成功');


        return $r;
    }


    /**
     * 设置页面标题
     *
     * @param $title
     * @throws \Exception
     */
    public function funcSetTitle($title)
    {
        $this->funcSetPageInfo('title', $title);
    }

    /**
     * 统计设置页面显示信息
     *
     * @param $k
     * @param $v
     * @throws \Exception
     */
    public function funcSetPageInfo($k, $v)
    {
        $page_info = $this->context()->get('common_page_info');
        if ($page_info == null)
        {
            $page_info = [];
        }

        $page_info[$k] = $v;
        $this->context()->set('common_page_info', $page_info);
    }


    /**
     * 重构返回
     *
     * @return XReturn
     * @throws \Exception
     */
    protected function commonR()
    {
        $r = parent::commonR();

        $page_info = $this->context()->get('common_page_info');
        $page_info['is_admin_edit'] = $this->funcIsAdminEdit();
        $r->setData('page_info', $page_info);

        return $r;
    }


    function onRequest(?string $action): ?bool
    {
        parent::onRequest($action);


        Log::funcLogDebug(__METHOD__, '验证TOKEN-BEGIN');
        $token = $this->token();
        if (H::funcStrIsNullOrEmpty($token))
        {
            $this->funcWriteErr(-555, '登陆超时，请重新登陆');
            return false;
        }

        //判断签名
        $app_user = $this->funcGetOAUser();
        if (!$app_user->funcCheckSign($token))
        {
            $this->funcWriteErr(-556, '登陆异常，请重新登陆[getSign]');
            return false;
        }
        Log::funcLogDebug(__METHOD__, '验证TOKEN-END');


        //判断权限
        if (H::funcStrToLower($this->getAppID()) != "z_common")
        {
            if (!$app_user->funcCheckRoleByAppID($this->getAppID()))
            {
                $this->funcWriteErr(-557, "权限不足[{$this->getAppID()}]");
                return false;
            }
        }


        return true;
    }
}